import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
import 'package:bip39/bip39.dart' as bip39;
import 'package:crypto/crypto.dart';
import 'package:web3dart/web3dart.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hex/hex.dart';
import '../models/wallet_model.dart';
import '../constants/wallet_constants.dart';

/// 钱包服务 - 核心钱包功能
class WalletService {
  static final WalletService _instance = WalletService._internal();
  factory WalletService() => _instance;
  WalletService._internal();
  
  final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
  final Random _random = Random.secure();
  
  /// 生成助记词
  String generateMnemonic() {
    return bip39.generateMnemonic();
  }
  
  /// 验证助记词
  bool validateMnemonic(String mnemonic) {
    return bip39.validateMnemonic(mnemonic);
  }
  
  /// 从助记词生成私钥
  Future<String> mnemonicToPrivateKey(String mnemonic, {String? passphrase}) async {
    try {
      // 从助记词生成种子
      final seed = bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
      
      // 使用 BIP44 路径派生以太坊私钥 (m/44'/60'/0'/0/0)
      // 这里简化实现，直接从种子生成私钥
      final privateKeyBytes = seed.sublist(0, 32);
      final privateKeyHex = HEX.encode(privateKeyBytes);
      
      return '0x$privateKeyHex';
    } catch (e) {
      throw Exception('生成私钥失败: $e');
    }
  }
  
  /// 生成随机私钥
  String generatePrivateKey() {
    final bytes = List<int>.generate(32, (i) => _random.nextInt(256));
    return '0x${bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join()}';
  }
  
  /// 从私钥获取地址
  String getAddressFromPrivateKey(String privateKey) {
    try {
      final credentials = EthPrivateKey.fromHex(privateKey);
      return credentials.address.hex;
    } catch (e) {
      throw Exception('获取地址失败: $e');
    }
  }
  
  /// 创建新钱包
  Future<WalletModel> createWallet({
    required String name,
    required String networkId,
    String? mnemonic,
  }) async {
    try {
      // 生成或使用提供的助记词
      final walletMnemonic = mnemonic ?? generateMnemonic();
      
      // 生成私钥
      final privateKey = await mnemonicToPrivateKey(walletMnemonic);
      
      // 获取地址
      final address = getAddressFromPrivateKey(privateKey);
      
      // 创建钱包模型
      final wallet = WalletModel(
        id: _generateWalletId(),
        name: name,
        address: address,
        networkId: networkId,
        createdAt: DateTime.now(),
      );
      
      // 安全存储私钥和助记词
      await _storeWalletSecrets(wallet.id, privateKey, walletMnemonic);
      
      return wallet;
    } catch (e) {
      throw Exception('创建钱包失败: $e');
    }
  }
  
  /// 导入钱包
  Future<WalletModel> importWallet({
    required String name,
    required String networkId,
    required String mnemonic,
  }) async {
    try {
      // 验证助记词
      if (!validateMnemonic(mnemonic)) {
        throw Exception('无效的助记词');
      }
      
      // 生成私钥
      final privateKey = await mnemonicToPrivateKey(mnemonic);
      
      // 获取地址
      final address = getAddressFromPrivateKey(privateKey);
      
      // 创建钱包模型
      final wallet = WalletModel(
        id: _generateWalletId(),
        name: name,
        address: address,
        networkId: networkId,
        createdAt: DateTime.now(),
      );
      
      // 安全存储私钥和助记词
      await _storeWalletSecrets(wallet.id, privateKey, mnemonic);
      
      return wallet;
    } catch (e) {
      throw Exception('导入钱包失败: $e');
    }
  }
  
  /// 从私钥导入钱包
  Future<WalletModel> importWalletFromPrivateKey({
    required String name,
    required String networkId,
    required String privateKey,
  }) async {
    try {
      // 验证私钥格式
      if (!privateKey.startsWith('0x') || privateKey.length != 66) {
        throw Exception('无效的私钥格式');
      }
      
      // 获取地址
      final address = getAddressFromPrivateKey(privateKey);
      
      // 创建钱包模型
      final wallet = WalletModel(
        id: _generateWalletId(),
        name: name,
        address: address,
        networkId: networkId,
        createdAt: DateTime.now(),
      );
      
      // 安全存储私钥
      await _storeWalletSecrets(wallet.id, privateKey, null);
      
      return wallet;
    } catch (e) {
      throw Exception('导入钱包失败: $e');
    }
  }
  
  /// 获取钱包私钥
  Future<String?> getWalletPrivateKey(String walletId) async {
    try {
      return await _secureStorage.read(key: 'wallet_${walletId}_private_key');
    } catch (e) {
      return null;
    }
  }
  
  /// 获取钱包助记词
  Future<String?> getWalletMnemonic(String walletId) async {
    try {
      return await _secureStorage.read(key: 'wallet_${walletId}_mnemonic');
    } catch (e) {
      return null;
    }
  }
  
  /// 删除钱包
  Future<void> deleteWallet(String walletId) async {
    try {
      await _secureStorage.delete(key: 'wallet_${walletId}_private_key');
      await _secureStorage.delete(key: 'wallet_${walletId}_mnemonic');
    } catch (e) {
      throw Exception('删除钱包失败: $e');
    }
  }
  
  /// 验证钱包密码
  Future<bool> verifyWalletPassword(String walletId, String password) async {
    try {
      final storedHash = await _secureStorage.read(key: 'wallet_${walletId}_password_hash');
      if (storedHash == null) return false;
      
      final passwordHash = sha256.convert(utf8.encode(password)).toString();
      return passwordHash == storedHash;
    } catch (e) {
      return false;
    }
  }
  
  /// 设置钱包密码
  Future<void> setWalletPassword(String walletId, String password) async {
    try {
      final passwordHash = sha256.convert(utf8.encode(password)).toString();
      await _secureStorage.write(key: 'wallet_${walletId}_password_hash', value: passwordHash);
    } catch (e) {
      throw Exception('设置密码失败: $e');
    }
  }
  
  /// 生成钱包 ID
  String _generateWalletId() {
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final random = _random.nextInt(9999).toString().padLeft(4, '0');
    return 'wallet_${timestamp}_$random';
  }
  
  /// 安全存储钱包密钥
  Future<void> _storeWalletSecrets(String walletId, String privateKey, String? mnemonic) async {
    try {
      // 存储私钥
      await _secureStorage.write(
        key: 'wallet_${walletId}_private_key',
        value: privateKey,
      );
      
      // 存储助记词（如果有）
      if (mnemonic != null) {
        await _secureStorage.write(
          key: 'wallet_${walletId}_mnemonic',
          value: mnemonic,
        );
      }
    } catch (e) {
      throw Exception('存储钱包密钥失败: $e');
    }
  }
  
  /// 导出钱包
  Future<Map<String, dynamic>> exportWallet(String walletId) async {
    try {
      final privateKey = await getWalletPrivateKey(walletId);
      final mnemonic = await getWalletMnemonic(walletId);
      
      if (privateKey == null) {
        throw Exception('钱包不存在');
      }
      
      return {
        'privateKey': privateKey,
        'mnemonic': mnemonic,
        'address': getAddressFromPrivateKey(privateKey),
      };
    } catch (e) {
      throw Exception('导出钱包失败: $e');
    }
  }
  
  /// 验证地址格式
  bool isValidAddress(String address) {
    try {
      EthereumAddress.fromHex(address);
      return true;
    } catch (e) {
      return false;
    }
  }
  
  /// 生成二维码数据
  String generateQRData(String address, {String? amount, String? tokenSymbol}) {
    final data = {
      'address': address,
      if (amount != null) 'amount': amount,
      if (tokenSymbol != null) 'token': tokenSymbol,
    };
    return jsonEncode(data);
  }
  
  /// 解析二维码数据
  Map<String, dynamic>? parseQRData(String qrData) {
    try {
      return jsonDecode(qrData) as Map<String, dynamic>;
    } catch (e) {
      return null;
    }
  }
}
